#ifndef WIN32_GAME_H
#define WIN32_GAME_H
#include <dsound.h>
#include <minwindef.h>
#include <windows.h>
#include <winnt.h>
#include <xinput.h>
#include <cstddef>
#include "game_platform.h"

// 添加这个去掉重复的冗余代码
struct win32_window_dimension {
    int32 Width;
    int32 Height;
};

struct win32_offscreen_buffer {
    BITMAPINFO Info;
    void* Memory;
    // 后备缓冲区的宽度和高度
    uint32 Width;
    uint32 Height;
    int32 Pitch;
    int32 BytesPerPixel;
};

struct win32_sound_output {
    // 音频测试
    uint32 RunningSampleIndex;  // 样本索引
    int32 SamplesPerSecond;     // 采样率：每秒采样48000次
    int32 BytesPerSample;       // 一个样本的大小
    DWORD SecondaryBufferSize;  // 缓冲区大小
    int32 LatencySampleCount;
    DWORD SafetyBytes;  // 安全值表示游戏更新循环可能会变化的样本数量
};

struct win32_debug_time_marker {
    // 当前音频输出设备播放指针的位置，用于标识正在播放的音频缓冲区位置
    DWORD OutputPlayCursor;
    // 当前音频输出设备写入指针的位置，用于标识下一个需要填充音频数据的位置
    DWORD OutputWriteCursor;
    // 音频输出时的当前位置，用于跟踪音频数据的具体写入点（可能与 OutputWriteCursor
    // 类似，但用途更具体）
    DWORD OutputLocation;
    // 已写入到音频缓冲区的字节数，用于统计音频数据量或调试
    DWORD OutputByteCount;
    // 预期的翻转指针位置（下一帧或下一块缓冲区的播放起始位置）
    DWORD ExpectedFlipCursor;
    // 在屏幕翻转（图形帧切换）时，音频播放指针的位置，用于同步音频和图形的关系
    DWORD FlipPlayCursor;
    // 在屏幕翻转时，音频写入指针的位置，用于调试音频数据的写入延迟
    DWORD FlipWriteCursor;
};

#define WIN32_STATE_FILE_NAME_COUNT MAX_PATH

// 定义一个结构体 win32_replay_buffer，表示一个重放缓冲区。
// 该结构体包含两个成员：
// - ReplayFileName：一个字符数组，保存重放文件的名称。
// - MemoryBlock：一个指针，指向用于存储重放数据的内存块。
struct win32_replay_buffer {
    // 文件句柄，用于表示打开的文件
    // 它将传递给 CreateFile 或其他与文件操作相关的 API 函数来执行文件的读写操作
    HANDLE FileHandle;

    // 文件映射句柄，用于表示文件映射对象
    // 它由 CreateFileMapping 创建，用于将文件映射到进程的虚拟内存空间
    // 通过该句柄可以在内存中直接操作文件内容，而无需进行传统的文件 I/O 操作
    HANDLE MemoryMap;

    // 存储重放文件名的字符数组，长度为 WIN32_STATE_FILE_NAME_COUNT。
    // 该文件名用来标识重放缓冲区的文件（如保存游戏状态或历史数据）。
    char ReplayFileName[WIN32_STATE_FILE_NAME_COUNT];

    // 指向内存块的指针，内存块用于存储重放相关的数据。
    // 该内存块会动态分配并使用，用于存储重放期间的数据，避免频繁访问磁盘。
    void* MemoryBlock;
};

struct win32_state {
    size_t TotalSize;
    // 游戏内存的总大小（以字节为单位）。
    // 用于保存整个游戏状态（包括所有需要保存的数据）。

    void* GameMemoryBlock;
    // 指向游戏内存块的指针。
    // 游戏状态的所有数据存储在该内存块中，便于保存和加载。

    win32_replay_buffer ReplayBuffers[4];

    HANDLE RecordingHandle;
    // 文件句柄，用于记录输入。
    // 当正在录制输入时，该句柄表示打开的录制文件。

    int InputRecordingIndex;
    // 标志变量，用于指示当前是否处于录制状态。
    // 0 表示未录制，非 0 表示正在录制，并可能标识录制的特定槽位。

    HANDLE PlaybackHandle;
    // 文件句柄，用于回放输入。
    // 当正在回放输入时，该句柄表示打开的回放文件。

    int InputPlayingIndex;
    // 标志变量，用于指示当前是否处于回放状态。
    // 0 表示未回放，非 0 表示正在回放，并可能标识回放的特定槽位。

    char EXEFileName[WIN32_STATE_FILE_NAME_COUNT];
    // 存储可执行文件的完整路径。
    // 用于引用当前运行程序的位置和名称。

    char* OnePastLastEXEFileNameSlash;
    // 指向可执行文件路径中最后一个路径分隔符后的字符位置。
    // 用于方便生成与可执行文件相关的其他路径或文件名。
};
enum win32_fader_state {
    Win32Fade_FadingIn,
    Win32Fade_WaitingForShow,
    Win32Fade_Inactive,
    Win32Fade_FadingGame,
    Win32Fade_FadingOut,
    Win32Fade_WaitingForClose,
};

struct win32_thread_startup {
    platform_work_queue* Queue;
};

#endif